package utils

import (
	"Three/project01/chatroom/common/message"
	"encoding/binary"
	"encoding/json"
	"fmt"
	"net"
)

// Transfer 将这些方法关联到结构体中
type Transfer struct {
	//分析它应该；有哪些字段
	Conn net.Conn
	Buf  [8096]byte //这是传输时使用的缓冲
}

func (this *Transfer) ReadPkg() (mes message.Message, err error) {
	//buf := make([]byte,8096)
	fmt.Println("读取服务器发送的数据...")
	//conn.Read在conn没有关闭时才会阻塞
	//如果客户端关闭了conn，则conn不会阻塞
	_, err = (*this).Conn.Read(this.Buf[:4])
	if err != nil {
		//fmt.Println("conn.Read err=",err)
		return
	}

	//根据buf[:4]转成一个uint32类型
	var pkglen uint32
	pkglen = binary.BigEndian.Uint32(this.Buf[:4])

	//根据pkglen读取消息内容
	n, err := this.Conn.Read(this.Buf[:pkglen])
	if n != int(pkglen) || err != nil {
		//err = errors.New("read pkg header error")
		return
	}

	//把读取到的信息buf反序列化成--->message.Message
	//技术就是一层窗户纸&mes!!
	err = json.Unmarshal(this.Buf[:pkglen], &mes)
	if err != nil {
		//err = errors.New("read pkg body error")
		return
	}
	return
}

func (this *Transfer) WritePkg(data []byte) (err error) {
	//先发送一个长度给对方
	var pkgLen uint32
	pkgLen = uint32(len(data))
	//var buf [4]byte
	binary.BigEndian.PutUint32(this.Buf[:4], pkgLen)
	//发送长度
	n, err := this.Conn.Write(this.Buf[:4])
	if n != 4 || err != nil {
		fmt.Println("conn.Write(buf) fail", err)
		return
	}
	fmt.Printf("客户端发送消息的长度%d,内容%s\n ", pkgLen, string(data))
	//发送data本身
	n, err = this.Conn.Write(data)
	if n != int(pkgLen) || err != nil {
		fmt.Println("conn.Write(buf) fail", err)
		return
	}
	return
}
